package com.jy.modules.cims.common.sysUtils;

import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Properties;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpException;
import com.jy.modules.cims.common.CimsConstant;
import com.jy.modules.cims.common.exception.CimsExceptionConstant;

/**
 * @description SFTP常用工具操作类。
 * @version v1.0
 * @author shengzhoutao
 * @Date 2015-8-20
 */
public class SFTPClientImpl implements IFTPClient {
	private String hostname;// FTP服务器IP地址
	private int port;// FTP端口号
	private String user;// FTP用户
	private String password;// FTP密码

	private Session session = null;
	private Channel channel = null;
	private ChannelSftp channelSftp = null;

	private static Logger logger = LoggerFactory.getLogger(SFTPClientImpl.class);

	/**
	 * @description 无参数构造函数
	 */
	public SFTPClientImpl() {

	}

	/**
	 * @description 有参数构造函数
	 */
	public SFTPClientImpl(String hostname, int port, String user, String Password) {
		this.init(hostname, port, user, Password);
	}

	/**
	 * @description 初始化参数
	 */
	public void init(String hostname, int port, String user, String Password) {
		this.hostname = hostname;
		this.port = port;
		this.user = user;
		this.password = Password;
	}

	/**
	 * @description 判断是否登入成功
	 * @return 成功：true；false：失败
	 * */
	public boolean ftpLogin() {
		boolean isLogin = false;
		try {
			JSch jsch = new JSch(); // 创建JSch对象
			// 根据用户名，主机ip，端口获取一个Session对象
			session = jsch.getSession(this.user, this.hostname, this.port);
			session.setPassword(this.password); // 设置密码

			Properties config = new Properties();
			config.put("StrictHostKeyChecking", "no");
			session.setConfig(config); // 为Session对象设置properties
			session.setTimeout(CimsConstant.FTP_DATA_TIMEOUT * 10); // 设置timeout时间
			session.connect(); // 通过Session建立链接

			channel = session.openChannel("sftp"); // 打开SFTP通道
			channel.connect(); // 建立SFTP通道的连接

			channelSftp = (ChannelSftp) channel;

			logger.info(CimsExceptionConstant.FTP_LOGIN_SUCCESS, this.user, this.hostname);
			isLogin = true;

			config = null;
			jsch = null;
		} catch (Exception e) {
			e.printStackTrace();
			logger.info(CimsExceptionConstant.FTP_LOGIN_FAIL, this.user, this.hostname, e.getMessage());
			isLogin = false;
		}

		return isLogin;
	}

	/**
	 * @description 退出关闭服务器链接
	 * */
	public void ftpLogOut() {
		if (channelSftp != null) {
			channelSftp.quit();
			channelSftp.disconnect();
		}
		if (channel != null) {
			channel.disconnect();
		}
		if (session != null) {
			session.disconnect();
		}

		logger.info(CimsExceptionConstant.FTP_LOGOUT_SUCCESS, this.user, this.hostname);
	}

	/***
	 * @description 上传Ftp文件
	 * @param localFile
	 *            当地文件
	 * @param romotUpLoadePath
	 *            上传服务器路径 应该以/结束
	 **/
	public boolean uploadFile(File localFile, String romotUpLoadePath) {
		if (null == channel) {
			return false;
		}

		try {
			if (!romotUpLoadePath.endsWith("/")) {
				romotUpLoadePath = romotUpLoadePath + "/";
			}

			// 创建目录
			mkdir(romotUpLoadePath);
			// 文件上传
			channelSftp.put(localFile.getAbsolutePath(), romotUpLoadePath, ChannelSftp.OVERWRITE);

			String oldFileName = localFile.getName();
			if(oldFileName.endsWith(".zip")){
				String newFileName = oldFileName.replace(".zip", "_ok.zip");
				try{
				  channelSftp.rm(newFileName);
				}catch(Exception e){
				}
				channelSftp.rename(romotUpLoadePath + oldFileName, newFileName);
			}
		
			logger.info("上传本地文件[{}]到FTP文件目录[{}]成功!", localFile.getAbsolutePath(), romotUpLoadePath);
		} catch (Exception e) {
			e.printStackTrace();
			logger.error(CimsExceptionConstant.FTP_UPLOAD_FILE_FAIL, localFile.getName(), romotUpLoadePath, e);
			return false;
		}

		return true;
	}

	public boolean downloadFile(String remoteFile, String localFile) {
		if (null == channel) {
			return false;
		}
		
		try {
			channelSftp.get(remoteFile, localFile);
			
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			logger.error(CimsExceptionConstant.FTP_DOWNLOAD_FILE_FAIL, remoteFile, localFile, e.getMessage());
		} 
		return false;
	}

	public boolean downloadFile(String remoteFile, OutputStream outputStream) {
		return false;
	}

	public boolean uploadDirectory(String localDirectory, String remoteDirectoryPath) {
		return false;
	}

	public boolean downLoadDirectory(String localDirectoryPath, String remoteDirectory) {
		return false;
	}

	public boolean existsFile(String remoteFile) throws IOException {
		return false;
	}

	/**
	 * @description 不存在目录，创建目录
	 * @param romotUpLoadePath
	 *            传服务器路径 应该以/结束
	 * @throws SftpException
	 */
	@SuppressWarnings("static-access")
	private void mkdir(String romotUpLoadePath) throws SftpException {
		String[] romotUpLoadePaths = romotUpLoadePath.split("/");
		StringBuffer path = new StringBuffer("/");
		for (int index = 0; index < romotUpLoadePaths.length; index++) {
			try {
				path.append(romotUpLoadePaths[index]).append("/");
				// 进入指定目录
				channelSftp.cd(path.toString());
			} catch (SftpException sException) {
				if (channelSftp.SSH_FX_NO_SUCH_FILE == sException.id) {
					// 创建目录
					channelSftp.mkdir(path.toString());
					// 进入指定目录
					channelSftp.cd(path.toString());
				}
			}
		}
	}

}
